
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:logger/logger.dart';
import 'package:shimmer/shimmer.dart';
import 'package:xim/common/style/colors.dart';
import 'package:xim/common/util/device.dart';
import 'package:xim/common/util/toast.dart';
import 'package:xim/config/theme_config.dart';
import 'package:xim/widget/common/state.dart';

abstract class GetStyleView<R extends Style> extends StatelessWidget{
  final log = Logger();
  final String? styleTag = null;

  GetStyleView({super.key});
  R get style => GetInstance().find<R>(tag: styleTag);

  Widget buildView(BuildContext context);

  @override
  Widget build(BuildContext context) {
    initModelColor(context);
    if(style.theme!=null){
      return Theme(
          data: style.theme!,
          child: buildView(context)
      );
    }
    return buildView(context);
  }

  void initModelColor(BuildContext context){
    var brightness = PlatformUtils.getBrightness(context);
    for(var color in style.modelColors){
      color.model = brightness;
    }
    log.i("curr brightness[$brightness]，init modelColor: ${style.modelColors.length}");
  }

}

abstract class GetStyleControllerView<D, T extends GetxStateMixinController<D>, R extends Style> extends GetView<T> {

  final log = Logger();

  GetStyleControllerView({super.key});

  final String? styleTag = null;

  R get style => GetInstance().find<R>(tag: styleTag);

  String get loadingHintText => "正在加载...";

  /// 加载文字提示样式
  TextStyle get loadingHintTextStyle => TextStyle(
      fontSize: 18.0,
      color: style.bgColor.color
  );

  @override
  Widget build(BuildContext context) {
    initModelColor(context);
    return controller.obx(
      (data) => buildView(context, data),
      onError: (String? errMsg){
        return errorWidget(errMsg);
      },
      onLoading: loadingWidget(),
    );
  }

  Widget buildView(BuildContext context, D? data);

  void initModelColor(BuildContext context){
    var brightness = PlatformUtils.getBrightness(context);
    for(var color in style.modelColors){
      color.model = brightness;
    }
    log.i("curr brightness[$brightness]，init modelColor: ${style.modelColors.length}");
  }

  Widget loadingWidget(){
    return Container(
      color: style.bgColor.color,
      child: Column(
        children: [
          Expanded(
              child: Container(
                color: Colors.transparent,
                child: Container(
                  color: style.bgColor.color,
                  child: Shimmer.fromColors(
                    baseColor: Colors.grey,
                    highlightColor: const Color(0x9E9E9E28),
                    child: Center(
                      child: Text(
                        loadingHintText,
                        textAlign: TextAlign.center,
                        style: loadingHintTextStyle,
                      ),
                    ),
                  ),
                ),
              )
          )
        ],
      ),
    );
  }

  Widget errorWidget(String? errorInfo){
    return SafeArea(
      child: Container(
        padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 12),
        color: style.bgColor.color,
        child: GestureDetector(
          onTap: (){
            controller.refreshPage();
          },
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Center(
                  child: Text('服务器异常，点击页面重试', style: TextStyle(color: style.textColor.color, fontSize: 16),)
              ),
              const SizedBox(height: 10,),
              Text('错误信息：$errorInfo', style: TextStyle(color: style.textColor.color, fontSize: 13),),
              Text('当前路由信息：${Get.currentRoute}', style: TextStyle(color: style.textColor.color, fontSize: 13),),
            ],
          ),
        ),
      ),
    );
  }

}

abstract class Style extends StyleConfig {

  ThemeData? get theme => null;

  @override
  List<ModelColor> get modelColors => [
    ...super.modelColors,
    appBarColor,
    bgColor,
    textColor,
    weakTextColor,
    weakBgColor,
  ];

  final appBarColor = ModelColor(
    lightColor:const Color(0xffededed),
    darkColor: const Color(0xff101010),
  );

  final ModelColor bgColor = ModelColor(
    lightColor:const Color(0xffffffff),
    darkColor: const Color(0xff181818),
  );

  final ModelColor weakBgColor = ModelColor(
    lightColor:const Color(0xffffffff),
    darkColor: const Color(0xff2c2c2c),
  );

  final textColor = ModelColor(
    lightColor:const Color(0xff171717),
    darkColor: const Color(0xffcfcfcf),
  );

  final weakTextColor = ModelColor(
    lightColor:const Color(0xffb2b2b2),
    darkColor: const Color(0xff5e5e5e),
  );

  /// 分割线
  Widget divider({
    BuildContext? context,
    Color? bgColor,
    double height=1,
    double? width,
    double verticalGap = 0,
    double horizontalGap = 0,
    double paddingGap=0}) {
    context ??= Get.context;
    bgColor ??= PlatformUtils.isDarkMode(context!)
        ? const Color(0xff2e2e2e)
        : const Color(0xffededed);
    return Container(
      margin: EdgeInsets.symmetric(vertical: verticalGap, horizontal: horizontalGap),
      padding: EdgeInsets.symmetric(vertical: paddingGap),
      height: height,
      width: width ?? 1.sw,
      decoration: BoxDecoration(color: bgColor,),
    );
  }

  Widget userAvatar(String avatar,{double circular=8, double width=50 }) {
    return ClipRRect(
        borderRadius: BorderRadius.all(Radius.circular(circular)),
        child: Image.network(avatar, width: width,)
    );
  }

}

abstract class IModelColor {

  List<ModelColor> get modelColors;

}

abstract class GetxStateMixinController<T> extends GetxController with StateMixin<T>{
  refreshPage(){
    change(null, status: RxStatus.loading());
    dataInit().then((value) => {
      change(value, status: RxStatus.success())
    }).catchError((err){
        change(null, status: RxStatus.error("cacheError:$err"));
        return err;
    });
  }

  /// 请求数据
  Future<T?> dataInit();

  @override
  void onInit() {
    super.onInit();
    refreshPage();
  }

  /// 底部对话框
  void showBottomSheet({
    required List<Widget> children,
    Color? bgColor,
    bool overlay=true,
    EdgeInsets? padding,
    BuildContext? context}) => ToastUtil.bottomSheet(
        children: children,
        bgColor: bgColor,
        overlay: overlay,
        padding: padding,
        context: context
    );

}

abstract class AppBarStyle extends Style with AppBarMixin {

}

